// MyGraphView.cpp : implementation file
//

#include "stdafx.h"
#include "waveeditor.h"

#include "waveeditorDoc.h"
#include "MyGraphFrame.h"	
#include "MyGraphView.h"
#include "MyGraphClockView.h"
#include "MyGraphInfoView.h"
#include "HighlightingRulesDialog.h"
#include "MyGraphButtonView.h"
#include "MySignalListDialog.h"
#include "MyColorDialog.h"
#include "Math.h"
#include "languagecomponents.h"
#include <list>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// MyGraphView
IMPLEMENT_DYNCREATE(GraphView, CScrollView)

const CString WAVE_CHANGE_INTEVAL_STRING = "<- %s%s ->";
const CString WAVE_HINT_STRING = "%s %s";

const static unsigned int MINMAL_SCROLL_PAGE_SIZE = 6;

struct SignalData
{
	SignalData(int Num, int StartPos, int EndPos)
	{
		num = Num ;
		start = StartPos;
		end = EndPos;
	}

	int num;
	int start;
	int end;
};

GraphView::GraphView()
{
	WindowIsOpened	=	FALSE;
	HorSi64.nPos = 0;
	GraphVerticalScrollPosition = 0;
	GridVisible = true;
}

GraphView::~GraphView()
{
}


BEGIN_MESSAGE_MAP(GraphView, CScrollView)
	//{{AFX_MSG_MAP(MyGraphView)
	ON_WM_KILLFOCUS()
	ON_WM_MOUSEMOVE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_WM_ERASEBKGND()
	ON_WM_RBUTTONDOWN()
	//}}AFX_MSG_MAP
	//ON_COMMAND(ID_GRAPH_PUTLEFTMARK					, OnGraphPutleftmark)
	//ON_COMMAND(ID_GRAPH_PUTLEFTMARKATTACHEDTOEDGE	, OnGraphPutleftmarkattachedtoedge)
	//ON_COMMAND(ID_GRAPH_PUTRIGHTMARK				, OnGraphPutrightmark)
	//ON_COMMAND(ID_GRAPH_PUTRIGHTMARKATTACHEDTOEDGE	, OnGraphPutrightmarkattachedtoedge)	
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONUP()
	ON_WM_RBUTTONDBLCLK()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_HSCROLL()
	ON_WM_MOUSEWHEEL()
	ON_WM_VSCROLL()
	ON_WM_KEYDOWN()
	ON_WM_WINDOWPOSCHANGING()
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// MyGraphView drawing

void GraphView::OnInitialUpdate()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	LastTipText = "";

	if ( m_ToolTip.Create( this, TTS_ALWAYSTIP ) && m_ToolTip.AddTool( this ) )
	{
		m_ToolTip.SetMaxTipWidth( SHRT_MAX );
		m_ToolTip.SetDelayTime (TTDT_AUTOPOP, SHRT_MAX);
		m_ToolTip.SetDelayTime (TTDT_INITIAL, 1000); 
		m_ToolTip.SetDelayTime (TTDT_RESHOW,  800);
	}

	SelectedScenario = pDoc->selectedscenario;

	pDoc->SetGraphVeiwHintState( false );
	pDoc->SetGraphViewHintPointer( &m_ToolTip );
	SetScrollSizes (MM_TEXT, CSize(0,pDoc->_script[SelectedScenario]->globalsignals->GetTotalSignalDelta()));
	CScrollView::OnInitialUpdate();

	//pDoc->graphtooltype		=	NORMALTOOL;
	myDC					=	NULL;
	InitialSetScrollInfo();
	EnableScrollBarCtrl( SB_HORZ );
	UpDateGraph();
}

void GraphView::OnDraw(CDC* pDC)
{
	ReadGraphData(pDC);
}

/////////////////////////////////////////////////////////////////////////////
// MyGraphView diagnostics

#ifdef _DEBUG
void GraphView::AssertValid() const
{
	CScrollView::AssertValid();
}

void GraphView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

ZWaveeditorDoc* GraphView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(ZWaveeditorDoc)));
	ASSERT_VALID( (ZWaveeditorDoc*)m_pDocument );
	return (ZWaveeditorDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// MyGraphView message handlers
BOOL GraphView::PreTranslateMessage(MSG* pMsg) 
{
    if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd)
    {
        switch(pMsg->message)
        {
        case WM_LBUTTONDOWN:    
        case WM_MOUSEMOVE:
        case WM_LBUTTONUP:    
        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:    
        case WM_RBUTTONUP:
        case WM_MBUTTONUP:
            m_ToolTip.RelayEvent(pMsg);
            break;
        }
    }
    return CView::PreTranslateMessage(pMsg);
}

void GraphView::ChangeWindowTitle()
{
	CFrameWnd* pFrame	=	GetParentFrame();
	ZWaveeditorDoc* pDoc = GetDocument();
	CString	name	=	"Graph View (";
	name			+=	pDoc->GetTitle()+")" + " - "+pDoc->GroupName;
	pFrame->SetWindowText(name);
}

void GraphView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	ChangeWindowTitle();
	UpDateGraph();
}

void GraphView::OnToolTipNeedText( bool bAlwaysShowHint )
{	
		if (( !bAlwaysShowHint ) && ( strcmp( LastTipText, CurrentTipText ) != 0 ))
			m_ToolTip.SendMessage ( TTM_POP );
		m_ToolTip.UpdateTipText( CurrentTipText, this );
		LastTipText = CurrentTipText;
}

void GraphView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	// TODO: Add your specialized code here and/or call the base class
	ChangeWindowTitle();	
//	ShowCursor(FALSE);
	CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}

void GraphView::OnKillFocus(CWnd* pNewWnd) 
{
	CScrollView::OnKillFocus(pNewWnd);
	ChangeWindowTitle()	;
	// TODO: Add your message handler code here

}

void GraphView::DrawVerGrid(
    ZWaveeditorDoc*& pDoc,
    int HorizontalWindowSize,
    int Height,
    CDC* pDC,
    int IndentOfGraphFromWindow )
{
    const graphdata &GraphData = pDoc->_script[SelectedScenario]->mygraphdata;

	CPoint LineCoordinates[2];
	LineCoordinates[0].y				=	0;
	LineCoordinates[1].y				=	Height;
	CPen Pen(PS_COSMETIC,1, RGB(180,180,180));

	CPen* OldPen = pDC->SelectObject(&Pen);

	if(( GraphData.graphdelta/2 ) < GraphData.globaldelta)
	{
        double Delta = HorizontalWindowSize / QUANTITY_HYPHENS;

		for(int i=0;i < ( QUANTITY_HYPHENS + 1 );i++)
		{
			LineCoordinates[0].x	=	LineCoordinates[1].x = i*Delta - IndentOfGraphFromWindow;
			pDC->Polyline(LineCoordinates,2);
		}
	}
	else
	{
		__int64 DrawXPosition = 0;
		int Step = 1;
		while( DrawXPosition < GraphData.globaldelta)
		{
			LineCoordinates[0].x = LineCoordinates[1].x	=
                GraphData.GetWindowCoordinate( DrawXPosition + GraphData.globaloffset) - IndentOfGraphFromWindow;

			pDC->Polyline( LineCoordinates, 2 );
			if(GraphData.globaldelta > QUANTITY_HYPHENS)
				DrawXPosition	= ((Step*GraphData.globaldelta) / QUANTITY_HYPHENS);
			else
				DrawXPosition	= Step;
			Step ++;
		}
	}

    pDC->SelectObject( OldPen );
}

void GraphView::DrawHorGridLine(
    CDC* pDC,
    int WindowHorizontalSize,
    int IndentOfGraphFromWindow,
    int Height)
{
    CPen Pen(PS_COSMETIC,1, RGB(180, 180, 180));
	CPen* OldPen = pDC->SelectObject(&Pen);
	CPoint DrawYPosition = CPoint( -IndentOfGraphFromWindow, Height );

	CPoint LineCoordinates[2];
	LineCoordinates[0] = LineCoordinates[1] = DrawYPosition;
	LineCoordinates[1].x += WindowHorizontalSize;
	pDC->Polyline( LineCoordinates, 2 );

    pDC->SelectObject(OldPen);
}

int GraphView::ReadGraphData(CDC* pOldDC)
{
	SetFocus();

	ZWaveeditorDoc* pDoc = GetDocument();

	CRect WindowSizes;
	GetClientRect(&WindowSizes);

	CDC* pDC = new CDC();
	pDC->CreateCompatibleDC(pOldDC);
	CBitmap* pNewBitmap = new CBitmap();
	pNewBitmap->CreateCompatibleBitmap(pOldDC,WindowSizes.right , WindowSizes.bottom );
	CBitmap* pOldBitmap = pDC->SelectObject(pNewBitmap);	

	ScenarioSignals* GlobalSignalsOfSelectedScript = pDoc->_script[SelectedScenario]->globalsignals;
	graphdata& GraphDataOfSelectedScript = pDoc->_script[SelectedScenario]->mygraphdata;
	GraphDataOfSelectedScript.SetDeltay( GlobalSignalsOfSelectedScript->GetGraphDeltaY() );

	int StartSignalPosition, EndSignalPosition;
	int LastSignalEndPosition = 0;
	CRect AreaFreeFromSignals;
	CRect SignalBackgroundArea;
	COLORREF SignalBackgroundColor;
	CPoint sigp;

	long IndentOfGraphFromWindow = GetIndentOfGraphFromWindow();
	long StartDrawingCoordinateY = this->GetScrollPos( SB_VERT );
	long EndDrawingCoordinateY = StartDrawingCoordinateY + WindowSizes.bottom;

	CBrush **brush;
	CPen **pen;
	int NumberOfPens = GraphDataOfSelectedScript.YSizeOfSignalDivider;
	pen = new CPen*[NumberOfPens];
	brush = new CBrush*[NumberOfPens];
	pen[0] = new CPen(PS_SOLID,1, RGB(64,64,64));
	brush[0] = new CBrush( RGB(64,64,64) );
	for( int i = 1; i < NumberOfPens; i++ )
	{
		pen[i] = new CPen(PS_SOLID,1, RGB(64+(i&1)*100,64+((i>>1)&1)*100,64+((i>>2)&1)*100));
		brush[i] = new CBrush( RGB(64+(i&1)*100,64+((i>>1)&1)*100,64+((i>>2)&1)*100));
	}

	CPen* pOldPen = pDC->SelectObject(pen[0]);
	CBrush* pOldBrush = pDC->SelectObject(brush[0]);
 
	if ( IndentOfGraphFromWindow < 0 )
	{
		AreaFreeFromSignals = CRect(0,0, -IndentOfGraphFromWindow, EndDrawingCoordinateY - StartDrawingCoordinateY );
		DrawRectangleInColor ( pDC, AreaFreeFromSignals, WHITE, WHITE );
	}
	else if ( IndentOfGraphFromWindow > 0 )
	{
		AreaFreeFromSignals = CRect( WindowSizes.right, 0, WindowSizes.right - IndentOfGraphFromWindow, EndDrawingCoordinateY - StartDrawingCoordinateY);
		DrawRectangleInColor ( pDC, AreaFreeFromSignals, WHITE, WHITE );
	}

	int signals_num	=	GlobalSignalsOfSelectedScript->GetNumberOfSignals();
	std::list<SignalData> SigData;
	std::list<SignalData>::iterator iter;
	
	for ( int i = 0; i < signals_num; i++ )
	{
		StartSignalPosition = GlobalSignalsOfSelectedScript->GetSignalPos(i);
		EndSignalPosition = GlobalSignalsOfSelectedScript->GetSignalEndPos(i);
		if ( GlobalSignalsOfSelectedScript->IfShowSignal(i) == TRUE 
			&& StartDrawingCoordinateY < EndSignalPosition 
			&& StartSignalPosition < EndDrawingCoordinateY )
			SigData.push_back(SignalData(i, StartSignalPosition, EndSignalPosition));
	}

	for ( iter = SigData.begin() ; iter != SigData.end(); iter++ )
	{
		LastSignalEndPosition = max( iter->end, LastSignalEndPosition );
		sigp	=	CPoint( -IndentOfGraphFromWindow, iter->start - StartDrawingCoordinateY );
		SignalBackgroundColor = GlobalSignalsOfSelectedScript->GetSignalBackgroundColor( iter->num );
		SignalBackgroundArea = CRect(sigp.x,sigp.y,sigp.x+pDoc->graphwindowMaxX, iter->end - StartDrawingCoordinateY );
		SetSignalBackgroundColor( pDC, SignalBackgroundColor, SignalBackgroundArea, iter->num, &GraphDataOfSelectedScript );
	}

	//Draw a vertical line immediately to the schedule laid down on the line
	if (GridVisible)
	{
		DrawVerGrid(
            pDoc, 
            WindowSizes.right, 
            LastSignalEndPosition - StartDrawingCoordinateY, 
            pDC, 
            IndentOfGraphFromWindow );
		for ( iter = SigData.begin() ; iter != SigData.end(); iter++ )
            DrawHorGridLine(pDC, WindowSizes.right, IndentOfGraphFromWindow, iter->end - StartDrawingCoordinateY);
	}

	for ( iter = SigData.begin() ; iter != SigData.end(); iter++ )
	{
		sigp	=	CPoint( -IndentOfGraphFromWindow, iter->start - StartDrawingCoordinateY );
		DrawSignal( pDC, iter->num, &sigp, pen, brush, &GraphDataOfSelectedScript );
	}

	long StartDrawingMarkCursorPosition = GetStartDrawingMarkCursorPosition( GraphDataOfSelectedScript.GetWindowCoordinate( GraphDataOfSelectedScript._1stmark.x_true) );
	DrawMarkCursor( pDC, StartDrawingMarkCursorPosition, RGB(0,255,0) );
	StartDrawingMarkCursorPosition = GetStartDrawingMarkCursorPosition( GraphDataOfSelectedScript.GetWindowCoordinate( GraphDataOfSelectedScript._2ndmark.x_true) );
	DrawMarkCursor( pDC, StartDrawingMarkCursorPosition, RGB(255,0,0) );

	AreaFreeFromSignals = CRect( 0, LastSignalEndPosition - StartDrawingCoordinateY, WindowSizes.right, EndDrawingCoordinateY - StartDrawingCoordinateY);
	DrawRectangleInColor ( pDC, AreaFreeFromSignals, WHITE, WHITE );
	
	pOldDC->SetViewportOrg( 0,0 );
	pOldDC->BitBlt( 0,
					0,
					WindowSizes.right,
					WindowSizes.bottom,
					pDC,
					0,
					0,
					SRCCOPY );

	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldBitmap);
	for( int i = 0; i < NumberOfPens; i++ )
	{
		delete pen[i];
		delete brush[i];
	}
	delete pDC;
	delete pNewBitmap;
	delete pen;
	delete brush;
	WindowIsOpened					=	TRUE;
	return 0;
}

void GraphView::DrawSignal( CDC* pDC, int NumberOfOriginalSignal, CPoint* sigp, CPen **pen, CBrush **brush, graphdata *GraphData )
{
	ScenarioSignals* GlobalSignalsOfSelectedScript = GetDocument()->_script[SelectedScenario]->globalsignals;
	int NumberOfPens = GraphData->YSizeOfSignalDivider;
	long ChangesInPage = GraphData->GetNumberOfSignals();
	int NumberOfSignalsInGroup = GlobalSignalsOfSelectedScript->GetSignalsInGroup( NumberOfOriginalSignal )->GetCount();
	CPoint pnt[8];
	for ( int j = 0; j < NumberOfSignalsInGroup; j++ )
	{
		int NumberOfSignal = (*GlobalSignalsOfSelectedScript->GetSignalsInGroup( NumberOfOriginalSignal ))[j];
		GraphData->SetSignalBar(NumberOfSignal,*sigp);
		pDC->SelectObject(pen[j%NumberOfPens]);
		pDC->SelectObject(brush[j%NumberOfPens]);
		for(int ii=0;ii<ChangesInPage;ii++)
		{
			int numofpoints	=	GraphData->GetPolyLineArrayForSignal(ii,NumberOfSignal,pnt);
			if(numofpoints >=0)
			{
				if(numofpoints < 4)
				{
					pDC->Polyline(pnt,numofpoints);
				}
				else
				{
					pDC->Polygon(pnt,numofpoints);
				}
			}
		}
		sigp->y += GlobalSignalsOfSelectedScript->GetDistanceBetweenTwoLinesInGroup();
	}
}

void GraphView::ScrollViewTarget( CPoint OldPoint, CPoint NewPoint )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	SCROLLINFO64 HorScrollInfo = GetHorzScrollInfo();
	SCROLLINFO VertScrollInfo = GetVertScrollInfo();

	graphdata &tmpGraphData = pDoc->_script[SelectedScenario]->mygraphdata;
	__int64 dX = tmpGraphData.GetTrueCoordinates( NewPoint.x ) - tmpGraphData.GetTrueCoordinates( OldPoint.x );
	HorScrollInfo.nPos -= dX; 

	int dY = NewPoint.y - OldPoint.y;
	VertScrollInfo.nPos -= dY;
	
	if (( HorScrollInfo.nPos > 0 ) && ( HorScrollInfo.nPos < HorScrollInfo.nMax - HorScrollInfo.nPage ))
	{
		HorScrollInfo.fMask = SIF_POS;
		SetScrollInfo64( SB_HORZ, HorScrollInfo );
	}

	if (( VertScrollInfo.nPos > 0 ) && ( VertScrollInfo.nPos < VertScrollInfo.nMax - VertScrollInfo.nPage ))
	{
		VertScrollInfo.fMask = SIF_POS;
		SetScrollInfo( SB_VERT, &VertScrollInfo );
	}

	__int64 NewPositionOfVisibleGraphArea = GetPositionOfGraphAreaFromScrollInfo( HorScrollInfo );
	SetGraphDataAndUpdateViews( NewPositionOfVisibleGraphArea, HorScrollInfo.nPage );
}

void GraphView::CatchMouseLeaveWindowArea()
{
	TRACKMOUSEEVENT     csTME;
    csTME.cbSize = sizeof(csTME);
    csTME.dwFlags = TME_LEAVE;
	csTME.hwndTrack = (HWND)(*this);
    ::_TrackMouseEvent(&csTME);
}

void GraphView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CScrollView::OnMouseMove(nFlags, point);
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;

	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT);
	OnGraphMouseMove(mypoint);

	CatchMouseLeaveWindowArea();
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case ZOOMTOOL:{
							if ( this == GetCapture() )
							{
								DrawSelectedArea(myDC,pDoc->linesforselection[0]);	
								pDoc->linesforselection[0].right	= point.x;
								pDoc->linesforselection[0].bottom	= point.y;
								DrawSelectedArea(myDC,pDoc->linesforselection[0]);	
							}
					  };break;
		case SCROLLTOOL:{
							if ( pDoc->mouseButtonState.LeftButton )
							{
								if ( 0 <= pDoc->mouseButtonState.LastPosition.x  ) 
									ScrollViewTarget( pDoc->mouseButtonState.LastPosition, point ); 
								pDoc->mouseButtonState.LastPosition.SetPoint( point.x, point.y );
							}
						};break;
		case NORMALTOOL:{
							OnToolTipNeedText( pDoc->GetGraphViewHintState() );
						}break;
	}
	
	DrawLineCursorInClock(pDoc->linesforselection[1].right);
	pDoc->linesforselection[1].right=	point.x;
	DrawLineCursorInClock(point.x);
}

LRESULT GraphView::OnMouseLeave(WPARAM wparam, LPARAM lparam)
{
	CurrentTipText = "";
	OnToolTipNeedText( false );
	ZWaveeditorDoc* pDoc = GetDocument();
	pDoc->mouseButtonState.LeftButton = false;
	pDoc->mouseButtonState.RightButton = false;
	return true;
}

HCURSOR GraphView::SetupCursor( BYTE CursorType  )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	HCURSOR tmpCursor = pDoc->graphNormalCursor;
	switch( CursorType )
	{
		case ZOOMTOOL:
			 tmpCursor = pDoc->graphZoomCursor; 
			 break;
		case SCROLLTOOL:
			 tmpCursor = pDoc->mouseButtonState.LeftButton ? pDoc->graphScrollCursorPush : pDoc->graphScrollCursor;
			 break;		
	}
	return SetCursor( tmpCursor );
}

void GraphView::OnDestroy() 
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->SetGraphWindowClosed();
	CScrollView::OnDestroy();
	// TODO: Add your message handler code here
}

void GraphView::UpDateGraph()
{
	CRect winrect;
	GetClientRect(&winrect);
	GetDocument()->graphwindowMaxX			=	winrect.right;
	Invalidate();	
}

void GraphView::OnSize(UINT nType, int cx, int cy) 
{
	// TODO: Add your message handler code here
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CRect winrect;
	GetClientRect(&winrect);

	pDoc->graphwindowMaxX	=	winrect.right;
	if(WindowIsOpened == TRUE)
	{
		//Here old scroll positions of vertical and horizontals are returned.
		//As it has been erased during changing of window sizes.
		SCROLLINFO64 Si64 = GetHorzScrollInfo();
		Si64.fMask = SIF_POS;
		SetScrollInfo64( SB_HORZ, Si64 );
		SetVerticalScrollInfo();
		Refresh();
	}
}

void GraphView::DrawLineCursor(int x)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	ChildGraphFrame	*pFrame	=	(ChildGraphFrame*) GetParentFrame();
	CDC		*pDC			=	pFrame->GetGraphWnd()->GetDC();
	CPen pen(PS_SOLID,1,RGB(200,64,64));
	CPen *oldpen	=	pDC->SelectObject(&pen);
	int oldmode		=	pDC->SetROP2(R2_NOT);
	int starty				=	0;
	int endy	=	pDoc->_script[SelectedScenario]->globalsignals->GetOnlySignalTotalDelta();
	pDC->MoveTo	(x,starty);
	pDC->LineTo	(x,endy);
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pFrame->GetGraphWnd()->ReleaseDC( pDC );
	DrawLineCursorInClock(x);
}

void GraphView::DrawMarkCursor(CDC* pDC, int x,COLORREF color)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	CPen pen(PS_SOLID,3,color);
	CPen *oldpen	=	pDC->SelectObject(&pen);
	int starty		=	0;
	int endy		=	pDoc->_script[SelectedScenario]->globalsignals->GetOnlySignalTotalDelta();
	pDC->MoveTo	( x-1, starty );
	pDC->LineTo	(x-1, endy);
	pDC->SelectObject(oldpen);
}

void GraphView::DrawRightLineCursor(int x)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	ChildGraphFrame	*pFrame	=	(ChildGraphFrame*) GetParentFrame();
	CDC		*pDC			=	pFrame->GetGraphWnd()->GetDC();
	CPen pen(PS_SOLID,1,RGB(0,255,255));
	CPen *oldpen	=	pDC->SelectObject(&pen);
	int oldmode		=	pDC->SetROP2(R2_XORPEN);
	int starty				=	0;
	int endy	=	pDoc->_script[SelectedScenario]->globalsignals->GetOnlySignalTotalDelta();
	pDC->MoveTo	(x,starty);
	pDC->LineTo	(x,endy);
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pFrame->GetGraphWnd()->ReleaseDC( pDC );
	//pDC->DeleteDC();
}

void GraphView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);
	CScrollView::OnLButtonUp(nFlags, point);
	
	pDoc->mouseButtonState.LeftButton = false;
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case ZOOMTOOL:{
							if(myDC == NULL)
							{
								return;
							}
							DrawSelectedArea(myDC,pDoc->linesforselection[0]);	
							delete myDC;
							myDC	=	NULL;
							ReleaseCapture();
							OnMouseZoomIn();
						};break;
		case SCROLLTOOL:{
							pDoc->mouseButtonState.LastPosition.SetPoint( -1, 0 );
						}break;
	}
}

int GraphView::OnMouseZoomIn(void)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();

	NormalizeZoomingBorders();
	
 	if((pDoc->linesforselection[0].right-pDoc->linesforselection[0].left)<5)
	{
		int OldIndentOfGraphFromWindow = GetIndentOfGraphFromWindow();
		ScrollInfo.nPage /= 2;
		ScrollInfo.fMask = SIF_PAGE;
		GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
		ScrollInfo.nMax = GetScrollSizeWithoutIndents() + GraphWindowIndent*2;
		__int64 PositionInGraph = pDoc->_script[SelectedScenario]->mygraphdata.GetNearestRealCoordinates(pDoc->linesforselection[0].left + OldIndentOfGraphFromWindow);
		ScrollInfo.nPos = PositionInGraph - ScrollInfo.nPage / 2 + GraphWindowIndent;
		return SetGraphInfoAfterZoomIn( ScrollInfo );
	}
	else
	{
		__int64 StartPositionOfGraphArea = pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates( pDoc->linesforselection[0].left  + GetIndentOfGraphFromWindow() );
		__int64 EndPositionOfGraphArea = pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates( pDoc->linesforselection[0].right  + GetIndentOfGraphFromWindow() );
		if ( StartPositionOfGraphArea < 0 && EndPositionOfGraphArea < 0 )
		{
			pDoc->StatusList.AddMessage("ERROR: Can Not Zoom In");
			pDoc->UpdateAllViews(0);
			return -1;
		}
		if ( StartPositionOfGraphArea == -1 )
		{
			StartPositionOfGraphArea = __int64((double)pDoc->linesforselection[0].left / pDoc->graphwindowMaxX * ScrollInfo.nPage) + ScrollInfo.nPos - GraphWindowIndent;
		}
		if ( EndPositionOfGraphArea == -1 )
		{
			EndPositionOfGraphArea = __int64((double)pDoc->linesforselection[0].right / pDoc->graphwindowMaxX * ScrollInfo.nPage) + ScrollInfo.nPos  - GraphWindowIndent;
		}

		if ( StartPositionOfGraphArea < 0 && (StartPositionOfGraphArea - __int64(double(StartPositionOfGraphArea - EndPositionOfGraphArea) / GraphWindowDivider)) < 0 )
		{
			StartPositionOfGraphArea = __int64( double( EndPositionOfGraphArea ) / ( 1 - GraphWindowDivider ) );
		}
		else if ( EndPositionOfGraphArea > GetScrollSizeWithoutIndents() && EndPositionOfGraphArea - GetScrollSizeWithoutIndents() - __int64(double(EndPositionOfGraphArea - StartPositionOfGraphArea) / GraphWindowDivider) > 0 )
		{
			EndPositionOfGraphArea = GetScrollSizeWithoutIndents() + __int64(double(GetScrollSizeWithoutIndents() - StartPositionOfGraphArea) / (GraphWindowDivider - 1));
		}

		ScrollInfo.nPage = EndPositionOfGraphArea - StartPositionOfGraphArea;
		GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
		ScrollInfo.nMax = GetScrollSizeWithoutIndents() + 2*GraphWindowIndent;
		ScrollInfo.nPos = ( StartPositionOfGraphArea + GraphWindowIndent < 0)? 0 : StartPositionOfGraphArea + GraphWindowIndent;
		
		return SetGraphInfoAfterZoomIn( ScrollInfo );
	}
}

int GraphView::SetGraphInfoAfterZoomIn( SCROLLINFO64 ScrollInfo )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->StatusList.ClearLog();

	NormalizeScrollPosition( &ScrollInfo );
	ScrollInfo.nMin = 0;
	ScrollInfo.fMask = SIF_ALL;
	
	if ( ScrollInfo.nPage < MINMAL_SCROLL_PAGE_SIZE )
	{
		GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( GetHorzScrollInfo().nPage );
		pDoc->StatusList.AddMessage("ERROR: Can Not Zoom In");
		pDoc->UpdateAllViews(0);
		return -1;
	}
	
	__int64 NewPositionOfVisibleGraphArea = GetPositionOfGraphAreaFromScrollInfo( ScrollInfo );

	SetScrollInfo64( SB_HORZ, ScrollInfo );

	SetGraphDataAndUpdateViews( NewPositionOfVisibleGraphArea, ScrollInfo.nPage );
	return 0;
}
void GraphView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);
	CScrollView::OnLButtonDown(nFlags, point);
	
	pDoc->mouseButtonState.LeftButton = true;
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case NORMALTOOL:{
							PutMark1(mypoint);
						};break;
		case ZOOMTOOL:{
							SetCapture();
							if(myDC != NULL)
							{
								delete myDC;
								myDC	=	NULL;
								return;
							}
							myDC = new CClientDC(this);
							pDoc->linesforselection[0].left	=	pDoc->linesforselection[0].right	= point.x;
							pDoc->linesforselection[0].top	=	pDoc->linesforselection[0].bottom	= point.y;
							DrawSelectedArea(myDC,pDoc->linesforselection[0]);	
					  };break;
		case SCROLLTOOL:{
							pDoc->mouseButtonState.LastPosition = point;
						}break;
	}
}

void GraphView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);
	CScrollView::OnRButtonDown(nFlags, point);
	
	pDoc->mouseButtonState.RightButton = true;
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case NORMALTOOL:{
							PutMark2(mypoint);
						};break;
		case ZOOMTOOL:	{
							OnZoomout();
						};break;
	}
}

/*int GraphView::PrepearSetMarkMenu(CPoint mpoint)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	CMenu contextmenu;
	contextmenu.LoadMenu(IDR_GRAPHTYPE);
	RECT rect;
	GetWindowRect(&rect);
	CMenu *graphmenu	=	contextmenu.GetSubMenu(0);
	for(int i=0;i<pDoc->_script[SelectedScenario]->globalsignals->GetNumberOfSignals();i++)
	{
		if((pDoc->_script[SelectedScenario]->globalsignals->IfShowSignal(i) == TRUE)&&(pDoc->_script[SelectedScenario]->globalsignals->IfShowSignal(i) == TRUE))
		{
			int _1stm	= 6000+i;
			int _2ndm	= 6100+i;
			CString menuitem	=	"Snap to edge (";
			menuitem	+= pDoc->_script[SelectedScenario]->globalsignals->GetSignalName(i) +")";
			graphmenu->GetSubMenu(0)->AppendMenu(MF_STRING,_1stm,(LPCTSTR)menuitem);
			graphmenu->GetSubMenu(1)->AppendMenu(MF_STRING,_2ndm,(LPCTSTR)menuitem);
		}
	}
	graphmenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,mpoint.x+rect.left,mpoint.y+rect.top,this);
	return 0;
}*/



void GraphView::DrawSelectedArea(CPoint p1,CPoint p2)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	CDC		*pDC			=	this->GetDC();
	HPEN pen				=	CreatePen(PS_SOLID,1,RGB(200,64,64));
	HPEN oldpen				=	(HPEN) SelectObject(pDC->m_hDC,pen);
	HBRUSH brush			=	CreateSolidBrush(RGB(200,64,64));
	HBRUSH oldbrush			=	(HBRUSH) SelectObject(pDC->m_hDC,brush);
	int oldmode				=	SetROP2(pDC->m_hDC,R2_NOT);
	int starty				=	0;
	int endy				=	pDoc->_script[SelectedScenario]->globalsignals->GetOnlySignalTotalDelta();
	Rectangle(pDC->m_hDC,p1.x,p1.y,p2.x,p2.y);
	SetROP2(pDC->m_hDC,oldmode);
	SelectObject(pDC->m_hDC,oldpen);
	SelectObject(pDC->m_hDC,oldbrush);
	DeleteObject(pen);
	DeleteObject(brush);
	this->ReleaseDC( pDC );
}

void GraphView::DrawSelectedArea(CDC *pDC,CRect rect)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	HPEN pen				=	CreatePen(PS_SOLID,1,RGB(200,64,64));
	HPEN oldpen				=	(HPEN) SelectObject(pDC->m_hDC,pen);
	HBRUSH brush			=	CreateSolidBrush(RGB(200,64,64));
	HBRUSH oldbrush			=	(HBRUSH) SelectObject(pDC->m_hDC,brush);
	int oldmode				=	SetROP2(pDC->m_hDC,R2_NOT);
	Rectangle(pDC->m_hDC,rect.left,rect.top,rect.right,rect.bottom);
	SetROP2(pDC->m_hDC,oldmode);
	SelectObject(pDC->m_hDC,oldpen);
	SelectObject(pDC->m_hDC,oldbrush);
	DeleteObject(pen);
	DeleteObject(brush);
}

void GraphView::DrawRedBar(CDC *pDC, CRect SignalBackgroundArea )
{
	SignalBackgroundArea.bottom--;
	SignalBackgroundArea.top++;
	DrawRectangleInColor ( pDC, SignalBackgroundArea, RGB(200,200,255), RGB(255,0,0) );
}

void GraphView::DrawGreenBar(CDC *pDC, CRect SignalBackgroundArea )
{
	DrawRectangleInColor ( pDC, SignalBackgroundArea, RGB(200,200,255), RGB(0,255,0) );
}

void GraphView::SetSignalBackgroundColor ( CDC* pDC, COLORREF SignalBackgroundColor, CRect SignalBackgroundArea, int NumberOfSignal, graphdata *GraphData )
{
	if(GraphData->_1stmark.signalID	==	NumberOfSignal )
	{
		DrawGreenBar(pDC, SignalBackgroundArea );
	}
	else
	{
		DrawRectangleInColor ( pDC, SignalBackgroundArea, SignalBackgroundColor, SignalBackgroundColor );
	}
	if(GraphData->_2ndmark.signalID	==	 NumberOfSignal)
	{
		DrawRedBar(pDC, SignalBackgroundArea );
	}
	CArray<RuleBorders,RuleBorders> *Borders = GraphData->GetRuleBordersForSignal( NumberOfSignal );
	if ( Borders == NULL )
	{
		return;
	}
	int StartXPosition = SignalBackgroundArea.left;
	int NumberOfBorders = Borders->GetCount();
	for ( int i = 0; i < NumberOfBorders; i++ )
	{
		SignalBackgroundArea.left = Borders->GetAt(i).Start * 2 + StartXPosition;
		SignalBackgroundArea.right = Borders->GetAt(i).End * 2 + 1 + StartXPosition;
		DrawRectangleInColor ( pDC, SignalBackgroundArea, RGB( 110, 110, 200 ), RGB( 110, 110, 200 ) );//RGB( 234, 128, 234 ), RGB( 234, 128, 234 ) );
	}
}

void GraphView::DrawRectangleInColor ( CDC* pDC, CRect Rect, COLORREF BrushColor, COLORREF PenColor )
{
	HPEN pen				=	CreatePen(PS_SOLID,1,PenColor);
	HPEN oldpen				=	(HPEN) SelectObject(pDC->m_hDC,pen);
	HBRUSH brush			=	CreateSolidBrush(BrushColor);
	HBRUSH oldbrush			=	(HBRUSH) SelectObject(pDC->m_hDC,brush);
	Rectangle( pDC->m_hDC, Rect.left, Rect.top, Rect.right, Rect.bottom );
	SelectObject(pDC->m_hDC,oldpen);
	SelectObject(pDC->m_hDC,oldbrush);
	DeleteObject(pen);
	DeleteObject(brush);
}
void GraphView::DrawLineCursorInClock(int x)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	ChildGraphFrame	*pFrame	=	(ChildGraphFrame*)	GetParentFrame();
	CRect RectOfClockWnd;
	pFrame->GetClockWnd()->GetClientRect( &RectOfClockWnd );
	CDC *pDC				=	pFrame->GetClockWnd()->GetDC();
	CPen pen(PS_SOLID,1,RGB(200,64,64));
	CPen *oldpen	=	pDC->SelectObject(&pen);
	int oldmode		=	pDC->SetROP2(R2_NOT);
	int starty				=	0;
	int endy	=	RectOfClockWnd.bottom;
	pDC->MoveTo	(x,starty);
	pDC->LineTo	(x,endy);
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pFrame->GetClockWnd()->ReleaseDC( pDC );
}

void GraphView::UpdateClockGraph()
{
	ChildGraphFrame	*pFrame		=	(ChildGraphFrame*)	GetParentFrame();
	GraphClockView* myclkview	=	(GraphClockView*)	pFrame->GetClockWnd();
	myclkview->UpdateView();
}

void GraphView::UpdateButtonView()
{
	ChildGraphFrame	*pFrame		=	(ChildGraphFrame*)	GetParentFrame();
	GraphButtonView* MyButtonView	=	(GraphButtonView*)	pFrame->GetGraphBut();
	MyButtonView->UpdateView();
}

void GraphView::UpdateInfoView()
{
	ChildGraphFrame	*pFrame		=	(ChildGraphFrame*)	GetParentFrame();
	GraphInfoView* MyInfoView	=	(GraphInfoView*)	pFrame->GetInfoWnd();
	MyInfoView->UpdateView();
}

void GraphView::DrawLineCursorSimple(int x)
{
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
	ChildGraphFrame	*pFrame	=	(ChildGraphFrame*) GetParentFrame();
	CDC		*pDC			=	pFrame->GetGraphWnd()->GetDC();
	CPen pen(PS_SOLID,1,RGB(200,64,64));
	CPen *oldpen	=	pDC->SelectObject(&pen);
	int oldmode		=	pDC->SetROP2(R2_NOT);
	int starty				=	0;
	int endy	=	pDoc->_script[SelectedScenario]->globalsignals->GetOnlySignalTotalDelta();
	pDC->MoveTo	(x,starty);
	pDC->LineTo	(x,endy);
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pFrame->GetGraphWnd()->ReleaseDC( pDC );
}


/*void GraphView::OnGraphPutleftmark()
{
	// TODO: Add your command handler code here
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true 
											=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.signalID		=	-1;
	DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	UpDateGraph();
	UpdateClockGraph();
	pDoc->OnMouseMove(mypoint);
}

void GraphView::OnGraphPutleftmarkattachedtoedge()
{
	// TODO: Add your command handler code here
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.signals_cut_x[0];
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.optimize		=	TRUE;
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.signalID		=	pDoc->_script[SelectedScenario]->globalsignals->GetSignalNumber(mypoint);
	DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	pDoc->Refresh();
	pDoc->OnMouseMove(mypoint);
}

void GraphView::OnGraphPutrightmark()
{
	// TODO: Add your command handler code here
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true 
											=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.signalID		=	-1;
	DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	UpDateGraph();
	UpdateClockGraph();
	pDoc->OnMouseMove(mypoint);
}

void GraphView::OnGraphPutrightmarkattachedtoedge()
{
	// TODO: Add your command handler code here
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.signals_cut_x[0];
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.optimize		=	TRUE;
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.signalID		=	pDoc->_script[SelectedScenario]->globalsignals->GetSignalNumber(mypoint);
	DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	pDoc->Refresh();
	pDoc->OnMouseMove(mypoint);
}*/




/*BOOL GraphView::OnCommand(WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	ZWaveeditorDoc* pDoc	= GetDocument();
	ASSERT_VALID(pDoc);
//---------------------- CHECK FOR MENU COMMANDS ------------------------------------------------------
	WORD nItemID = wParam;
	if(((wParam >>16)==0 )&&(lParam == 0))
	{
		if((nItemID>=6000)&&(nItemID<=6000+pDoc->_script[SelectedScenario]->globalsignals->GetNumberOfSignals()))
		{
			pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
			pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.signals_cut_x[0];
			pDoc->_script[SelectedScenario]->mygraphdata._1stmark.optimize		=	TRUE;
			pDoc->_script[SelectedScenario]->mygraphdata._1stmark.signalID		=	nItemID-6000;
			DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
			pDoc->Refresh();
			pDoc->OnMouseMove(mypoint);
		}
		if((nItemID>=6100)&&(nItemID<=6100+pDoc->_script[SelectedScenario]->globalsignals->GetNumberOfSignals()))
		{
			pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mypoint.x);
			pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.signals_cut_x[0];
			pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.optimize		=	TRUE;
			pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.signalID		=	nItemID-6100;
			DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
			pDoc->Refresh();
			pDoc->OnMouseMove(mypoint);
		}
	}
//-------------------------------------------------------------------------------------------------------
	return CScrollView::OnCommand(wParam, lParam);
}*/



void GraphView::OnRButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);

	CScrollView::OnRButtonUp(nFlags, point);
	SetupCursor( pParentFrame->graphtooltype );
	pDoc->mouseButtonState.RightButton = false;
}

void GraphView::PutMark1(CPoint mpoint)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true 
											=	pDoc->_script[SelectedScenario]->mygraphdata.GetNearestRealCoordinates(mpoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.signalID		=	-1;
	//DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	UpDateGraph();
	UpdateClockGraph();
//	pDoc->OnMouseMove(mypoint);
}
void GraphView::PutMark2(CPoint mpoint)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true 
											=	pDoc->_script[SelectedScenario]->mygraphdata.GetNearestRealCoordinates(mpoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.signalID		=	-1;
	//DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	UpDateGraph();
	UpdateClockGraph();
//	pDoc->OnMouseMove(mypoint);
}

void GraphView::SnapMark1(CPoint mpoint)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetNearestRealCoordinates(mpoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.globaloffset;//signals_cut_x[0];
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.optimize		=	TRUE;
	pDoc->_script[SelectedScenario]->mygraphdata._1stmark.signalID		=	pDoc->_script[SelectedScenario]->globalsignals->GetSignalNumber(mpoint);
	//DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	Refresh();
}
void GraphView::SnapMark2(CPoint mpoint)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_relative	=	pDoc->_script[SelectedScenario]->mygraphdata.GetNearestRealCoordinates(mpoint.x);
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true		=	pDoc->_script[SelectedScenario]->mygraphdata.globaloffset;//signals_cut_x[0];
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.optimize		=	TRUE;
	pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.signalID		=	pDoc->_script[SelectedScenario]->globalsignals->GetSignalNumber(mpoint);
	//DrawLineCursor(pDoc->linesforselection[pDoc->linesforselectionstatus].right);
	Refresh();
}
void GraphView::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);

	CScrollView::OnRButtonDblClk(nFlags, point);
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case NORMALTOOL:{
							SnapMark2(mypoint);
						};break;
		case ZOOMTOOL:	{
							OnZoomout();
						};break;
	}
}

void GraphView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ASSERT_VALID(pDoc);
	mypoint	=	point;
	mypoint.x += GetIndentOfGraphFromWindow();
	mypoint.y			+=	GetScrollPos(SB_VERT   );
	OnGraphMouseMove(mypoint);

	CScrollView::OnLButtonDblClk(nFlags, point);
	SetupCursor( pParentFrame->graphtooltype );
	switch(pParentFrame->graphtooltype)
	{
		case NORMALTOOL:{
							SnapMark1(mypoint);
						};break;
		case ZOOMTOOL:{
							SetCapture();
							if(myDC != NULL)
							{
								delete myDC;
								myDC	=	NULL;
								return;
							}
							myDC = new CClientDC(this);
							pDoc->linesforselection[0].left	=	pDoc->linesforselection[0].right	= point.x;
							pDoc->linesforselection[0].top	=	pDoc->linesforselection[0].bottom	= point.y;
							DrawSelectedArea(myDC,pDoc->linesforselection[0]);	
					  };break;
	}

}

void GraphView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	__int64	OldPositionOfVisibleGraphArea	=	ScrollInfo.nPos;
	__int64	NewPositionOfVisibleGraphArea;

	switch (nSBCode)
	{
	case SB_ENDSCROLL:
		{
			return;
		}
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		{
			ScrollInfo.nPos = GetScrollTrackPos64( SB_HORZ, SIF_TRACKPOS, ScrollInfo.nMax );
			break;
		}
	case SB_TOP:
		{
			ScrollInfo.nPos = 0;
			break;
		}
	case SB_LINELEFT:
		{
			ScrollInfo.nPos -= ScrollInfo.nPage / 10 + 1;
			break;
		}
	case SB_PAGELEFT:
		{
			ScrollInfo.nPos -= ScrollInfo.nPage;
			break;
		}
	case SB_BOTTOM:
		{
			ScrollInfo.nPos = ScrollInfo.nMax - ScrollInfo.nPage;
			break;
		}
	case SB_LINERIGHT:
		{
			ScrollInfo.nPos += ScrollInfo.nPage / 10 + 1;
			break;
		}
	case SB_PAGERIGHT:
		{
			ScrollInfo.nPos += ScrollInfo.nPage;
			break;
		}
	}
	NormalizeScrollPosition( &ScrollInfo );
	NewPositionOfVisibleGraphArea = GetPositionOfGraphAreaFromScrollInfo( ScrollInfo );
	if ( NewPositionOfVisibleGraphArea == OldPositionOfVisibleGraphArea &&
		IsBoundaryGraphPositionReached( NewPositionOfVisibleGraphArea ) == FALSE )
	{
		if ( nSBCode == SB_LINERIGHT )
		{
			NewPositionOfVisibleGraphArea++;
		}
		else if ( nSBCode == SB_LINELEFT )
		{
			NewPositionOfVisibleGraphArea--;
		}
	}
	ScrollInfo.fMask = SIF_POS;
	SetScrollInfo64( SB_HORZ, ScrollInfo );
	SetGraphDataAndUpdateViews( NewPositionOfVisibleGraphArea, ScrollInfo.nPage );
}

//Function activated by mouse wheel
BOOL GraphView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: Add your message handler code here and/or call default

	// If key "Shift" is pressed, horisontal scroll bar should be used
	if ( (nFlags & MK_SHIFT) != 0 )
	{
		OnHScroll( (zDelta > 0 ) ? SB_LINELEFT : SB_LINERIGHT, 0, 0 );
		return TRUE;
	}
	else if ( (nFlags & MK_CONTROL) != 0 )
	{
		SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
		if ( zDelta > 0 )
		{
			UINT64 OldPageSize = ScrollInfo.nPage;
			__int64 OldGraphWindowIndent = GraphWindowIndent;
			ScrollInfo.nPage = __int64((double)ScrollInfo.nPage / (ZOOM_MULTIPLIER + 1));
			GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
			ScrollInfo.nPos = ScrollInfo.nPos - OldGraphWindowIndent + (OldPageSize-ScrollInfo.nPage) / 2 + GraphWindowIndent;
			ScrollInfo.nMax = GetScrollSizeWithoutIndents() + 2*GraphWindowIndent;
			SetGraphInfoAfterZoomIn( ScrollInfo );
		}
		else
		{
			Zoomout( ZOOM_MULTIPLIER );
		}
		return TRUE;
	}
	//else we handle usual vertical scrolling
	else
	{
		return CScrollView::OnMouseWheel( nFlags, zDelta, pt );
	}
}

BOOL GraphView::InitialSetScrollInfo()
{
	return ( InitialSetHorizontalScrollInfo() && SetVerticalScrollInfo() );
}

BOOL GraphView::InitialSetHorizontalScrollInfo()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	SCROLLINFO64 ScrollInfo;

	ZeroMemory(&ScrollInfo, sizeof(ScrollInfo));
    ScrollInfo.cbSize = sizeof(ScrollInfo);
	ScrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
	ScrollInfo.nMin = 0;
	__int64 TotalSize = GetScrollSizeWithoutIndents();
	ScrollInfo.nPage = TotalSize;
	GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
	ScrollInfo.nMax = ScrollInfo.nPage + GraphWindowIndent*2;
	ScrollInfo.nPos = GraphWindowIndent;
	return SetScrollInfo64( SB_HORZ, ScrollInfo );
}

BOOL GraphView::SetVerticalScrollInfo()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	CRect WinRect;
	SCROLLINFO ScrollInfo;

	GetClientRect( &WinRect );

	ZeroMemory(&ScrollInfo, sizeof(ScrollInfo));
    ScrollInfo.cbSize = sizeof(ScrollInfo);
	ScrollInfo.fMask = SIF_ALL;
	ScrollInfo.nMin = 0;
	ScrollInfo.nMax = pDoc->_script[SelectedScenario]->globalsignals->GetTotalSignalDelta();
	ScrollInfo.nPage = WinRect.bottom;
	ScrollInfo.nPos = GraphVerticalScrollPosition;
	BOOL Result = SetScrollInfo( SB_VERT, &ScrollInfo );
	if ( ScrollInfo.nPage >= ScrollInfo.nMax )
	{
		EnableScrollBarCtrl( SB_VERT, FALSE );
	}
	return Result;
}

long GraphView::GetStartDrawingMarkCursorPosition( long WindowCoordinateFromGraph )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	long IndentOfGraphFromWindow = GetIndentOfGraphFromWindow();
	return (long)IntervalCompare( WindowCoordinateFromGraph - IndentOfGraphFromWindow,
														0, 
														pDoc->graphwindowMaxX );
}

SCROLLINFO GraphView::GetVertScrollInfo( /*short unsigned int flag*/ )
{
	SCROLLINFO ScrollInfo;
	ZeroMemory(&ScrollInfo, sizeof(ScrollInfo));
    ScrollInfo.cbSize = sizeof(ScrollInfo);
	CWnd::GetScrollInfo( /*flag*/SB_VERT, &ScrollInfo, SIF_ALL );
	return ScrollInfo;
}

SCROLLINFO64 GraphView::GetHorzScrollInfo()
{
	return HorSi64;
}

void GraphView::OnShift( BYTE ShiftDirection)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	__int64	OldPositionOfVisibleGraphArea	=	pDoc->_script[SelectedScenario]->mygraphdata.GetOffset();
	__int64	SizeOfVisibleGraphArea	=	pDoc->_script[SelectedScenario]->mygraphdata.GetPageLength();
	__int64	NewPositionOfVisibleGraphArea;

	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	if ( ShiftDirection == RIGHT )
	{
		ScrollInfo.nPos += ScrollInfo.nPage / 5;
	}
	else if ( ShiftDirection == LEFT )
	{
		ScrollInfo.nPos -= ScrollInfo.nPage / 5;
	}
	NormalizeScrollPosition( &ScrollInfo );
	NewPositionOfVisibleGraphArea = GetPositionOfGraphAreaFromScrollInfo( ScrollInfo );
	if ( NewPositionOfVisibleGraphArea == OldPositionOfVisibleGraphArea &&
		IsBoundaryGraphPositionReached( NewPositionOfVisibleGraphArea ) == FALSE )
	{
		if ( ShiftDirection == RIGHT )
		{
			NewPositionOfVisibleGraphArea++;
			ScrollInfo.nPos++;
		}
		else if ( ShiftDirection == LEFT )
		{
			NewPositionOfVisibleGraphArea--;
			ScrollInfo.nPos--;
		}
	}
	ScrollInfo.fMask = SIF_POS;
	SetScrollInfo64( SB_HORZ, ScrollInfo );
	SetGraphDataAndUpdateViews( NewPositionOfVisibleGraphArea, SizeOfVisibleGraphArea );
}

void GraphView::OnZoomin()
{
	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	ScrollInfo.nPage /= 2;
	__int64 OldGraphWindowIndent = GraphWindowIndent;
	GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
	ScrollInfo.nPos = ScrollInfo.nPos - OldGraphWindowIndent + ScrollInfo.nPage / 2 + GraphWindowIndent;
	ScrollInfo.nMax = GetScrollSizeWithoutIndents() + GraphWindowIndent * 2;
	
	SetGraphInfoAfterZoomIn( ScrollInfo );
}

void GraphView::OnZoomout()
{
	Zoomout( 1 );
}

void GraphView::Zoomout( double ZoomMultiplier )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->StatusList.ClearLog();

	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	if ( ScrollInfo.nPage >= ScrollInfo.nMax - 2*GraphWindowIndent )
	{
		pDoc->StatusList.AddMessage("ERROR: Can Not Zoom Out");
		pDoc->UpdateAllViews(0);
		return;
	}
	__int64 OldPageSize = ScrollInfo.nPage;
	ScrollInfo.nPage = UINT64(( ZoomMultiplier + 1) * ScrollInfo.nPage);
	__int64 OldGraphWindowIndent = GraphWindowIndent;
	NormalizeScrollPage( &ScrollInfo );
	GraphWindowIndent = ComputeGraphWindowIndentFromPageSize( ScrollInfo.nPage );
	ScrollInfo.nMax = GetScrollSizeWithoutIndents() + GraphWindowIndent * 2;
	ScrollInfo.nPos = ScrollInfo.nPos - OldGraphWindowIndent - ( ScrollInfo.nPage - OldPageSize ) / 2 + GraphWindowIndent;
	NormalizeScrollPosition( &ScrollInfo );
	ScrollInfo.nMin = 0;
	ScrollInfo.fMask = SIF_ALL;
	__int64 NewPositionOfVisibleGraphArea = GetPositionOfGraphAreaFromScrollInfo( ScrollInfo );
	

	SetScrollInfo64( SB_HORZ, ScrollInfo );

	SetGraphDataAndUpdateViews( NewPositionOfVisibleGraphArea, ScrollInfo.nPage );
}

void GraphView::NormalizeScrollPosition( SCROLLINFO64 *ScrollInfo )
{
	ScrollInfo->nPos = IntervalCompare( ScrollInfo->nPos, 0, ScrollInfo->nMax - ScrollInfo->nPage );
	return;
}

void GraphView::NormalizeScrollPage( SCROLLINFO64 *ScrollInfo )
{
	ScrollInfo->nPage = IntervalCompare( ScrollInfo->nPage, 0, GetScrollSizeWithoutIndents() );
	return;
}

__int64 GraphView::GetPositionOfGraphAreaFromScrollInfo( SCROLLINFO64 ScrollInfo )
{
	return IntervalCompare( ScrollInfo.nPos - GraphWindowIndent, 0, ScrollInfo.nMax - ScrollInfo.nPage - 2*GraphWindowIndent );
}

BOOL GraphView::IsBoundaryGraphPositionReached( __int64 NewPositionOfVisibleGraphArea )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	__int64	SizeOfWholeGraphArea	=	pDoc->_script[SelectedScenario]->mygraphdata.GetTotalSize();
	__int64	SizeOfVisibleGraphArea = pDoc->_script[SelectedScenario]->mygraphdata.GetPageLength();
	if ( NewPositionOfVisibleGraphArea == 0 || NewPositionOfVisibleGraphArea == SizeOfWholeGraphArea - SizeOfVisibleGraphArea )
	{
		return TRUE;
	}
	return FALSE;
}

long GraphView::GetIndentOfGraphFromWindow()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	__int64 StartDrawingCoordinateX = GetStartDrawingCoordinateX();
	return long((double(ScrollInfo.nPos - StartDrawingCoordinateX) / (__int64)ScrollInfo.nPage) * pDoc->graphwindowMaxX) ;
}

__int64 GraphView::GetStartDrawingCoordinateX()
{
	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	return IntervalCompare( ScrollInfo.nPos, GraphWindowIndent, ScrollInfo.nMax - ScrollInfo.nPage - GraphWindowIndent );
}

CString GraphView::GetOriginalTimeType()
{
	return GetDocument()->_script[SelectedScenario]->GetOriginalTimeType();
}

void GraphView::NormalizeZoomingBorders()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->linesforselection[0].left	< 0)				pDoc->linesforselection[0].left	= 0;
	if(pDoc->linesforselection[0].right	< 0)				pDoc->linesforselection[0].right	= 0;
	if(pDoc->linesforselection[0].left	> pDoc->graphwindowMaxX)	pDoc->linesforselection[0].left	= pDoc->graphwindowMaxX;
	if(pDoc->linesforselection[0].right	> pDoc->graphwindowMaxX)	pDoc->linesforselection[0].right	= pDoc->graphwindowMaxX;
	if(pDoc->linesforselection[0].right	<	pDoc->linesforselection[0].left)
	{
		int Temp	=	pDoc->linesforselection[0].right;
		pDoc->linesforselection[0].right	=	pDoc->linesforselection[0].left;
		pDoc->linesforselection[0].left	=	Temp;
	}
}

void GraphView::OnChooseColor()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->CheckIfGraphWindowOpened() == TRUE)
	{
		MyColorDialog ColorDialog;
		INT_PTR ReturnedValue = ColorDialog.DoModal();
		switch ( ReturnedValue )
		{
		case FAIL:
			{
				AfxMessageBox("Dialog box was unable to be created!");
				break;
			}
		case IDOK:
			{
				int NumberOfSignals = pDoc->_script[SelectedScenario]->globalsignals->GetNumberOfSignals();
				for ( int i = 0; i < NumberOfSignals; i++ )
				{
					if ( pDoc->_script[SelectedScenario]->globalsignals->CheckIfSignalMarked( i ) == TRUE )
					{
						pDoc->_script[SelectedScenario]->globalsignals->SetSignalBackgroundColor( ColorDialog.ChosenColor, i );
					}
				}
				pDoc->_script[SelectedScenario]->globalsignals->RemoveMarksFromSignals();
				break;
			}
		case IDCANCEL:
		default:
			{
				break;
			}
		}
		pDoc->SetGraphWindowClosed();
		pDoc->UpdateAllViews(0);
		pDoc->SetGraphWindowOpened();
	}
}

void GraphView::OnSetHighlightingRules()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->CheckIfGraphWindowOpened() == TRUE)
	{
		HighlightingRulesDialog HRDialog( pDoc->_script[SelectedScenario]->mygraphdata.GetTotalSize(), pDoc->_script[SelectedScenario]->GetCurrentTimeType() );
		INT_PTR ReturnedValue = HRDialog.DoModal();
		switch ( ReturnedValue )
		{
		case -1:
			{
				AfxMessageBox("Dialog box was unable to be created!");
				return;
			}
		case IDOK:
			{
				pDoc->_script[SelectedScenario]->globalsignals->SetRulesForMarkedSignals( pDoc->_script[SelectedScenario]->ConvertTimeToOriginalType( HRDialog.GetMin() ),
																						  pDoc->_script[SelectedScenario]->ConvertTimeToOriginalType( HRDialog.GetMax() ), 
																						  HRDialog.GetTypeOfRule() );
				break;
			}
		case ID_DEL_RULES:
			{
				pDoc->_script[SelectedScenario]->globalsignals->DeleteRulesForMarkedSignals();
				break;
			}
		case IDCANCEL:
		default:
			{
				return;
			}
		}
		pDoc->_script[SelectedScenario]->globalsignals->RemoveMarksFromSignals();
		Refresh();
		UpDateGraph();
		UpdateButtonView();
	}
	return;
}

BOOL GraphView::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;//CScrollView::OnEraseBkgnd(pDC);
}

void GraphView::OnUnGroup()
{
	GetDocument()->_script[SelectedScenario]->Ungroup();
}

void GraphView::OnGroupWaves()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	scenario* CurrentScenario = pDoc->_script[SelectedScenario];
	CString NameOfWavesignalsGroup;
	if ( CurrentScenario->globalsignals->AddNewGroupFromMarked( NameOfWavesignalsGroup ) )
	{
		CPoint FirstMarked;
		FirstMarked.x = 0;
		FirstMarked.y = CurrentScenario->globalsignals->GetMinPositionOfMarkedSignals();

		CurrentScenario->CreateGroupOfWavesignalsForEachSimpleGroupInScenario( NameOfWavesignalsGroup );
		Refresh();
		OnRemoveSignals();
		CurrentScenario->globalsignals->PushSignalInColumn(CurrentScenario->globalsignals->GetNumberOfSignals()-1, FirstMarked);
	}
}

ChildGraphFrame * GraphView::GetParentGraphFrame()
{
	return (ChildGraphFrame *)GetParentFrame();
}

void GraphView::OnGraphMouseMove(CPoint mousepoint)
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CString s1stmark	="Marker1: ";
	CString s2ndmark	="Marker2: ";
	CString sdelta		="Marker2-Marker1 : ";
    pDoc->SetDispStatusBar0Value( sdelta.GetLength(), s1stmark.GetLength(), s2ndmark.GetLength() );
	
	CString SignalNameInGroup = pDoc->_script[SelectedScenario]->GetSignalNameInGroupFromGraphView( mousepoint );

	CString tmpCommentString;
	__int64 lTempInterval = pDoc->_script[SelectedScenario]->GetDistanceAndCommentBetweenNearestChanges( mousepoint, tmpCommentString );

	CString tmpIntervalString = "";
	if ( lTempInterval >= 0 )
		tmpIntervalString.Format( WAVE_CHANGE_INTEVAL_STRING, Long64ToCString(lTempInterval), pDoc->_script[SelectedScenario]->GetCurrentTimeType());
	CurrentTipText.Format( WAVE_HINT_STRING, tmpIntervalString, tmpCommentString );
	if ( 1 == CurrentTipText.GetLength() ) CurrentTipText.Empty();

	CString SignalStatisticsText = "";

	if ( SignalNameInGroup != "" )
	{
		ResultWaveSignalStatistics SignalStatistics = GetSignalsStatistics( SignalNameInGroup );
		if ( SignalStatistics.MaxTimeInLevel[0] != 0 || SignalStatistics.MaxTimeInLevel[1] != 0 )
		{
			SignalStatisticsText += "(Low Level,High Level)(Max,Mean,Min) "+Long64ToCString(SignalStatistics.MaxTimeInLevel[0])+" "+Long64ToCString(SignalStatistics.MeanTimeInLevel[0])+" "+Long64ToCString(SignalStatistics.MinTimeInLevel[0])+" : ";
			SignalStatisticsText += Long64ToCString(SignalStatistics.MaxTimeInLevel[1])+" "+Long64ToCString(SignalStatistics.MeanTimeInLevel[1])+" "+Long64ToCString(SignalStatistics.MinTimeInLevel[1]);
		}
	}

	s1stmark += Long64ToCString( pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true );
	s2ndmark += Long64ToCString( pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true );
	sdelta += Long64ToCString( pDoc->_script[SelectedScenario]->mygraphdata._2ndmark.x_true-pDoc->_script[SelectedScenario]->mygraphdata._1stmark.x_true );
	
	CArray<CString> TextToStatusBar;
	TextToStatusBar.SetSize( 0, 1 );
	TextToStatusBar.Add( sdelta );
	TextToStatusBar.Add( s1stmark );
	TextToStatusBar.Add( s2ndmark );
	TextToStatusBar.Add( pDoc->_script[SelectedScenario]->mygraphdata.GetTrueCoordinates(mousepoint) );

	CArray<int> ColorsOfText;
	ColorsOfText.SetSize( 0, 1 );
	ColorsOfText.Add( RGB(0,0,0) );
	ColorsOfText.Add( RGB(0,96,0) );
	ColorsOfText.Add( RGB(255,0,0) );

	CArray<int> SizesOfText;
	SizesOfText.SetSize( 0, 1 );
	SizesOfText.Add( 200 );
	SizesOfText.Add( 150 );
	SizesOfText.Add( 150 );
	SizesOfText.Add( 100 );
	pDoc->SetGraphStatusBarText( &TextToStatusBar, &ColorsOfText, &SizesOfText, 0 );

	TextToStatusBar.RemoveAll();
	//TextToStatusBar.Add( CurrentTipText ); // This future isn't useful with current status bar
	TextToStatusBar.Add( "Signal : " + SignalNameInGroup );
	TextToStatusBar.Add( SignalStatisticsText );

	ColorsOfText.RemoveAll();

	SizesOfText.RemoveAll();
	//SizesOfText.Add( 300 ); // This future isn't useful with current status bar
	SizesOfText.Add( 200 );
	SizesOfText.Add( 416 );
	pDoc->SetGraphStatusBarText( &TextToStatusBar, &ColorsOfText, &SizesOfText, 1 );
}

ResultWaveSignalStatistics GraphView::GetSignalsStatistics( CString SignalName )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	int SignalNumber = pDoc->_script[SelectedScenario]->globalsignals->GetSignalNumber( SignalName );
	scenario* Scenario = pDoc->_script[SelectedScenario];
	ResultWaveSignalStatistics ResultSignalStatistics;
	WaveSignalStatistics SignalStatisticsFromGroup = Scenario->GetStatisticsOfWavesignalInShownGroup( SignalNumber );
	double TempMeanTime;
	for (int i = 0; i < 2; i++ )
	{
		ResultSignalStatistics.MinTimeInLevel[i] = SignalStatisticsFromGroup.MinTimeInLevel[i];
		ResultSignalStatistics.MaxTimeInLevel[i] = SignalStatisticsFromGroup.MaxTimeInLevel[i];
		
		if ( SignalStatisticsFromGroup.NumberOfLevels[i] != 0 )
		{
			TempMeanTime = (double)SignalStatisticsFromGroup.SumOfTimesInLevel[i] / SignalStatisticsFromGroup.NumberOfLevels[i];
			ResultSignalStatistics.MeanTimeInLevel[i] = ( 0.5 + (__int64)TempMeanTime < TempMeanTime )?(__int64)TempMeanTime+1:(__int64)TempMeanTime;
		}
		else
		{
			ResultSignalStatistics.MeanTimeInLevel[i] = 0;
		}
	}
	return ResultSignalStatistics;
}

void GraphView::OnRemoveSignals()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->CheckIfGraphWindowOpened() == TRUE)
	{
		pDoc->_script[SelectedScenario]->globalsignals->RemoveMarkedSignals();
		SetVerticalScrollInfo();
		UpDateGraph();
		UpdateButtonView();
	}
}

void GraphView::OnDeletePermanently()
{
	if ( AfxMessageBox( "Are you sure you want to delete marked signals permanently?\nIf you like to return them back, you should load data file again.", MB_YESNO ) == IDYES )
	{
		ZWaveeditorDoc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		if(pDoc->CheckIfGraphWindowOpened() == TRUE)
		{
			pDoc->_script[SelectedScenario]->DeleteMarkedSignalsPermanently();
			SetVerticalScrollInfo();
			UpDateGraph();
			UpdateButtonView();
		}
	}
}

void GraphView::OnAddSignals()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your command handler code here
	if(pDoc->CheckIfGraphWindowOpened() == TRUE)
	{
		MySignalListDialog myd( pDoc->_script[SelectedScenario]->globalsignals );
		myd.DoModal();
		SetVerticalScrollInfo();
		UpDateGraph();
		UpdateButtonView();
	}
}

void GraphView::Refresh()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	SCROLLINFO64 ScrollInfo = GetHorzScrollInfo();
	SetGraphDataAndUpdateViews( GetPositionOfGraphAreaFromScrollInfo( ScrollInfo ), ScrollInfo.nPage );
}

void GraphView::GetWholeGraphChart( CImage *ImageForSave, graphdata *ImageGraphData )
{
	CDC *GraphViewDC = CDC::FromHandle( ImageForSave->GetDC() );
	DrawWholeGraphChart( GraphViewDC, ImageGraphData );
	ImageForSave->ReleaseDC();
}

int GraphView::DrawWholeGraphChart( CDC *pDC, graphdata *ImageGraphData )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	__int64 HorizontalSize = ImageGraphData->GetSizeInPixels( ImageGraphData->GetPageLength() );

	ScenarioSignals* GlobalSignalsOfSelectedScript = pDoc->_script[SelectedScenario]->globalsignals;

	ImageGraphData->SetDeltay( pDoc->_script[SelectedScenario]->globalsignals->GetGraphDeltaY() );
	int StartSignalPosition, EndSignalPosition;
	CRect SignalBackgroundArea;

	int signals_num	=	GlobalSignalsOfSelectedScript->GetNumberOfSignals();
	COLORREF SignalBackgroundColor;
	CPoint sigp;

	CBrush **brush;
	CPen **pen;
	int NumberOfPens = ImageGraphData->YSizeOfSignalDivider;
	pen = new CPen*[NumberOfPens];
	brush = new CBrush*[NumberOfPens];
	pen[0] = new CPen(PS_SOLID,1, RGB(64,64,64));
	brush[0] = new CBrush( RGB(64,64,64) );
	for( int i = 1; i < NumberOfPens; i++ )
	{
		pen[i] = new CPen(PS_SOLID,1, RGB(64+(i&1)*100,64+((i>>1)&1)*100,64+((i>>2)&1)*100));
		brush[i] = new CBrush( RGB(64+(i&1)*100,64+((i>>1)&1)*100,64+((i>>2)&1)*100));
	}
	CPen* pOldPen = pDC->SelectObject(pen[0]);
	CBrush* pOldBrush = pDC->SelectObject(brush[0]);

	long ChangesInPage = ImageGraphData->GetNumberOfSignals();
	for (int i = 0; i < signals_num; i++ )
	{
		if ( GlobalSignalsOfSelectedScript->IfShowSignal(i) == TRUE )
		{
			StartSignalPosition = GlobalSignalsOfSelectedScript->GetSignalPos(i);
			EndSignalPosition = GlobalSignalsOfSelectedScript->GetSignalEndPos(i);

			sigp	= CPoint( 0, StartSignalPosition );

			SignalBackgroundColor = GlobalSignalsOfSelectedScript->GetSignalBackgroundColor( i );
			SignalBackgroundArea = CRect( sigp, CPoint(HorizontalSize, EndSignalPosition ) );
			SetSignalBackgroundColor( pDC, SignalBackgroundColor, SignalBackgroundArea, i, ImageGraphData );

			DrawSignal( pDC, i, &sigp, pen, brush, ImageGraphData );
		}
	}

	/*long StartDrawingMarkCursorPosition = ImageGraphData->GetWindowCoordinate(ImageGraphData->_1stmark.x_true);
	DrawMarkCursor( pDC, StartDrawingMarkCursorPosition, RGB(0,255,0) );
	StartDrawingMarkCursorPosition = ImageGraphData->GetWindowCoordinate(ImageGraphData->_2ndmark.x_true);
	DrawMarkCursor( pDC, StartDrawingMarkCursorPosition, RGB(255,0,0) );*/

	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
	for( int i = 0; i < NumberOfPens; i++ )
	{
		delete pen[i];
		delete brush[i];
	}
	delete pen;
	delete brush;
	return 0;
}

__int64 GraphView::GetScrollSizeWithoutIndents()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	return pDoc->_script[SelectedScenario]->mygraphdata.GetTotalSize();
}

__int64 GraphView::ComputeGraphWindowIndentFromPageSize( __int64 PageSize )
{
	return PageSize / GraphWindowDivider + 1;
}

void GraphView::SetGraphDataAndUpdateViews( __int64 StartPositionOfVisibleGraphArea,
										    __int64 SizeOfVisibleGraphArea )
{
	ZWaveeditorDoc* pDoc = GetDocument();
	CString GroupName	=	pDoc->_script[SelectedScenario]->mygraphdata.GetGroupName();
	pDoc->_script[ SelectedScenario ]->InitGraphData( &(pDoc->_script[ SelectedScenario ]->mygraphdata),	
													  GroupName,
													  StartPositionOfVisibleGraphArea,
													  SizeOfVisibleGraphArea,
													  pDoc->graphwindowMaxX);
	UpDateGraph();
	UpdateClockGraph();
	UpdateInfoView();
	UpdateButtonView();
}

void GraphView::OnChangeMsUs()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	if ( pDoc->_script[SelectedScenario]->GetOriginalTimeType() == "us" )
	{
		pDoc->_script[SelectedScenario]->ChangeTimeDivider();
		CString GroupName	=	pDoc->_script[SelectedScenario]->mygraphdata.GetGroupName();
		pDoc->OnGraphView( SelectedScenario, GroupName );
	}
}

void GraphView::OnReloadLogWithChosenProperties()
{
	GetDocument()->OnReloadLogWithChosenProperties( SelectedScenario );
}

bool GraphView::SourceIsLog()
{
	ZWaveeditorDoc* pDoc = GetDocument();
	CString FileName = pDoc->_script[SelectedScenario]->GetFileNameOnly();
	if ( GetFileExtension( FileName ) == "log" || GetFileExtension( FileName ) == "txt" )
		return true;
	return false;
}

void GraphView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	if ( nSBCode == SB_THUMBTRACK )
	{
		SCROLLINFO ScrollInfo;
		ZeroMemory(&ScrollInfo, sizeof(ScrollInfo));
		ScrollInfo.cbSize = sizeof(ScrollInfo);
		GetScrollInfo( SB_VERT, &ScrollInfo, SIF_ALL );
		CScrollView::OnVScroll(nSBCode, ScrollInfo.nTrackPos, pScrollBar);
	}
	else
		CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
	Invalidate();
}

void GraphView::DisplaceToFirstChangeAndMaxZoomin()
{
	// We get access to signal data
	ChildGraphFrame*	pParentFrame = (ChildGraphFrame*)GetParentFrame();
	ZWaveeditorDoc* pDoc = GetDocument();
	int SignalNum = pDoc->_script[SelectedScenario]->globalsignals->GetMinYMarkedSignal();
	int GroupNum = pDoc->_script[SelectedScenario]->GetNumberOfGroupByName( pDoc->GetGroupName(), 3 ,FALSE);
	__int64 FirstSignalChange = pDoc->_script[SelectedScenario]->GetFirstTimingChangeAfterTime( GroupNum, SignalNum, 0);
	if ( FirstSignalChange == -1 )
		return;
	// We form scrolling
	SCROLLINFO64 HorScrollInfo = GetHorzScrollInfo();
	HorScrollInfo.nPos = GraphWindowIndent + FirstSignalChange;
	HorScrollInfo.nPage = MINMAL_SCROLL_PAGE_SIZE;
	if (( HorScrollInfo.nPos > 0 ) && ( HorScrollInfo.nPos < HorScrollInfo.nMax - HorScrollInfo.nPage ))
		SetGraphInfoAfterZoomIn(HorScrollInfo);
}

void GraphView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	switch ( nChar )
	{
	case VK_PRIOR:
	case VK_NEXT:
		{
			int ScrollDirection = ( nChar == VK_PRIOR )? SB_LINEUP : SB_LINEDOWN;
			GetParentSplitter( this, TRUE )->
				PostMessage( WM_VSCROLL, ScrollDirection, (LPARAM)GetScrollBarCtrl( SB_VERT )->m_hWnd );
			break;
		}
	case VK_HOME:
		{
			DisplaceToFirstChangeAndMaxZoomin();
			break;
		}
	}
}

void GraphView::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
	CScrollView::OnWindowPosChanging(lpwndpos);
	//Here current positions of scroll-bars are saved.
	//It is made as during changing window sizing these scroll positions are initiated with 0;
	GraphVerticalScrollPosition = GetScrollPos( SB_VERT );
}



const static ULONG WIN16_SCROLLBAR_MAX = 0x7fff;
const static ULONG WIN32_SCROLLBAR_MAX = 0x7fffffff;

BOOL GraphView::SetScrollInfo64( int     nBar, 
								SCROLLINFO64 &Si64, 
								BOOL    fRedraw
								)
{
    SCROLLINFO si = { sizeof(si), Si64.fMask };

    // normal scroll range requires no adjustment
    if(Si64.nMax <= WIN32_SCROLLBAR_MAX)
    {
        si.nMin  = (int)0;
		si.nMax  = (int)Si64.nMax;
        si.nPage = (int)Si64.nPage;
        si.nPos  = (int)Si64.nPos;
    }
    // scale the scrollrange down into allowed bounds
    else
    {
        si.nMin  = (int)0;
        si.nMax  = (int)WIN16_SCROLLBAR_MAX;
        si.nPage = (int)(Si64.nPage / (Si64.nMax / WIN16_SCROLLBAR_MAX) + 1);
        si.nPos  = (int)(Si64.nPos / (Si64.nMax / WIN16_SCROLLBAR_MAX));
    }
	HorSi64 = Si64;
	return SetScrollInfo( nBar, &si, fRedraw );
}

__int64 GraphView::GetScrollTrackPos64( int     nBar, 
							int     fMask, 
							UINT64  nMax64)
{
    SCROLLINFO si = { sizeof(si), fMask | SIF_PAGE};
    UINT64     nPos32;

    if(!GetScrollInfo(nBar, &si))
        return 0;

    nPos32 = (fMask & SIF_TRACKPOS) ? si.nTrackPos : si.nPos;

	if(nMax64 <= WIN32_SCROLLBAR_MAX)
    {
        return nPos32;
    }
    // special-case: scroll position at the very end
    else if(nPos32 == WIN16_SCROLLBAR_MAX - si.nPage + 1)
    {
        return nMax64 - si.nPage + 1;
    }
    // normal scroll range requires no adjustment

    // adjust the scroll position to be relative to maximum value
    else
    {
        return nPos32 * (nMax64 / WIN16_SCROLLBAR_MAX);
    }
}

void GraphView::SetVisibleOrInvisibleGrid()
{
	GridVisible = !GridVisible;
}